import json           # 用于处理JSON数据
import uuid           # 用于生成唯一ID
from rest_framework.views import APIView     # Django REST框架的视图类
from rest_framework.response import Response # Django REST框架的响应类
from dashscope import Generation             # 阿里云DashScope AI服务
import redis                                 # Redis数据库客户端
from django.conf import settings             # Django配置
# 连接到Redis数据库
redis_client = redis.Redis(
    host=settings.REDIS_CONFIG['host'],      # Redis主机地址
    port=settings.REDIS_CONFIG['port'],      # Redis端口
    db=settings.REDIS_CONFIG['db'],          # Redis数据库编号
    decode_responses=True,                   # 自动解码响应
    encoding='utf-8'                         # 强制使用UTF-8编码
)
# 多轮对话API视图类
class MutChatAPIView(APIView):
    # 处理POST请求的方法
    def post(self, request):
        # 从请求中获取对话ID和用户消息
        conversation_id = request.data.get('conversation_id')  # 对话ID
        message = request.data.get('message')                  # 用户消息
        # 检查消息是否为空
        if not message:
            # 如果消息为空，返回错误响应
            return Response({'error': '消息不能为空'}, status=400)
            
        # 如果没有对话ID，创建新的对话
        if not conversation_id:
            # 生成新的对话ID和空消息列表
            conversation_id, messages = str(uuid.uuid4()), []
        else:
            # 如果有对话ID，从Redis获取历史消息
            history = redis_client.get(f"qa:conversation:{conversation_id}")
            # 如果有历史记录则解析，否则使用空列表
            messages = json.loads(history) if history else []
            
        # 将用户消息添加到消息列表
        messages.append({"role": "user", "content": message})
        # 调用AI模型
        try:
            # 调用DashScope API
            response = Generation.call(
                api_key="sk-2c036d80d14a443f8769e072bb09a2e1",  # API密钥
                model="qwen-plus",                               # 使用的模型
                messages=messages,                               # 对话历史
                result_format="message",                         # 结果格式
            )
            # 获取AI回复
            assistant_message = response.output.choices[0].message.content
            # 将AI回复添加到消息列表
            messages.append({"role": "assistant  ", "content": assistant_message})
            # 将对话历史保存到Redis（7天过期）
            redis_client.setex(f"qa:conversation:{conversation_id}", 86400 * 7, json.dumps(messages))
            # 返回成功响应
            return Response({
                'conversation_id': conversation_id,  # 对话ID
                'answer': assistant_message,         # AI回复
                'messages': messages                 # 完整对话历史
            })
        except Exception as e:
            # 如果出现异常，返回错误响应
            # 确保错误信息使用UTF-8编码，避免emoji字符导致的编码问题
            try:
                error_msg = str(e).encode('utf-8', errors='ignore').decode('utf-8')
            except UnicodeError:
                error_msg = "系统内部错误"
            return Response({'error': error_msg}, status=500)






class CreateConversationView(APIView):
    """创建新对话"""
    def post(self, request):
        conversation_id = str(uuid.uuid4())
        title = request.data.get('title', '新对话')
        # 保存会话信息
        session_info = {
            'conversation_id': conversation_id,
            'title': title,
            'created_at': str(uuid.uuid4())[:8]  # 简化时间戳
        }
        redis_client.setex(f"qa:session:{conversation_id}", 86400 * 7, json.dumps(session_info))
        return Response({
            'conversation_id': conversation_id,
            'title': title
        })


class GetConversationHistoryView(APIView):
    """获取对话历史"""
    def get(self, request, conversation_id):
        # 获取对话历史
        history = redis_client.get(f"qa:conversation:{conversation_id}")
        session_info = redis_client.get(f"qa:session:{conversation_id}")
        if not history:
            return Response({'error': '对话不存在'}, status=404)
        messages = json.loads(history)
        session_data = json.loads(session_info) if session_info else None
        return Response({
            'conversation_id': conversation_id,
            'messages': messages,
            'session_info': session_data
        })




class ListConversationsView(APIView):
    """获取对话列表"""
    def get(self, request):
        # 获取所有会话
        pattern = "qa:session:*"
        keys = redis_client.keys(pattern)
        conversations = []
        for key in keys:
            session_data = redis_client.get(key)
            if session_data:
                session_info = json.loads(session_data)
                conversations.append(session_info)
        return Response({
            'conversations': conversations,
            'total': len(conversations)
        })
